/**
 * Created with CLion.
 * Description: 
 * User: loong
 * Date: 2021-03-19
 * Time: 8:29
 */
#include "Arrow.h"

Arrow::Arrow(DiagramBaseItem *startItem, DiagramBaseItem *endItem, LineType type, QGraphicsItem *parent)
        : QGraphicsPathItem(parent)
          , start_item_(startItem)
          , end_item_(endItem)
          , line_type_(type)
          , start_item_id_(start_item_->data(DiagramBaseItem::IDData).toString())
          , end_item_id_(end_item_->data(DiagramBaseItem::IDData).toString())
          , color_(Qt::black)
          , arrow_style_(ArrowStyle::Triangle)
{
    setFlag(QGraphicsItem::ItemIsSelectable, true);
    /*[NOTE] 2021/3/16 16:22 loong: (颜色，线宽，线形，线帽(线尾部形状)，连接点样式)*/
    setPen(QPen(color_, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
}

QRectF Arrow::boundingRect() const
{
    qreal extra = pen().width() + 20;

    return path().boundingRect().adjusted(-extra, -extra, extra, extra);
}

QPainterPath Arrow::shape() const
{
    /*[NOTE] 2021/3/17 8:38 loong:返回默认形状并添加箭头 */
    QPainterPath path = this->path();
    path.addPolygon(arrow_head_);
    return path;
}

void Arrow::UpdatePosition()
{
    //qDebug() << "old:" << start_item_->GetPropertyValue("Width")
    //         << start_item_->GetPropertyValue("Height");
    switch (line_type_) {
        case StraightLine:
            DrawStraightLine();
            break;
        case RightAngleLine:
            DrawRightAngleLine();
            break;
    }
    //qDebug() << "new:" << start_item_->GetPropertyValue("Width")
    //         << start_item_->GetPropertyValue("Height");
}

void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    /*[NOTE] 2021/3/17 9:06 loong:检测碰撞 */
    if (start_item_->collidesWithItem(end_item_))
        return;

    QPen myPen = pen();
    myPen.setColor(color_);
    painter->setPen(myPen);
    painter->setBrush(Qt::transparent);

    switch (line_type_) {
        case StraightLine:
            DrawStraightLine();
            break;
        case RightAngleLine:
            DrawRightAngleLine();
            break;
    }

    painter->drawPath(path());

    /*[1]: 为箭头设置填充色 */
    painter->setBrush(color_);
    painter->drawPolygon(arrow_head_);

    /*[NOTE] 2021/3/16 17:48 loong:如果箭头被选中，将将画两条与箭头平行的虚线 */
    /*if (isSelected()) {
        painter->setPen(QPen(color_, 1, Qt::DashLine));
        QLineF myLine = line();
        myLine.translate(0, 4.0);
        painter->drawLine(myLine);
        myLine.translate(0,-8.0);
        painter->drawLine(myLine);
    }*/
}

void Arrow::DrawRightAngleLine()
{
    QPointF start_point = start_item_->GetInPoint();
    QPointF end_point = end_item_->GetOutPoint();

    double y_offset = end_point.y() - start_point.y();

    QPainterPath path;
    path.moveTo(start_point);
    path.lineTo(start_point.x(), start_point.y() + y_offset / 2);
    path.lineTo(end_point.x(), end_point.y() - y_offset / 2);
    path.lineTo(end_point);

    setPath(path);
    setZValue(-1000);

    line_.setPoints(QPointF(end_point.x(), end_point.y() - y_offset / 2), end_point);
    //qDebug()<< line_;

    /*[2]:  为线的末端绘制箭头*/
    CalculateArrow(end_point);
}

void Arrow::DrawStraightLine()
{
    /*[1]:  确定连接线位置*/
    /*[NOTE]: 注意：箭头方向与逻辑抽取方向相反 */
    QPainterPath path;
    path.moveTo(start_item_->GetInPoint());
    path.lineTo(end_item_->GetOutPoint());

    setPath(path);

    line_.setPoints(start_item_->GetInPoint(), end_item_->GetOutPoint());

    /*[2]:  为线的末端绘制箭头*/
    CalculateArrow(end_item_->GetOutPoint());
}

void Arrow::DrawCurveLine()
{

}

void Arrow::CalculateArrow(QPointF point)
{
    /*[1]: 绘制箭头 */
    qreal arrowSize = 20;

    double angle = std::atan2(-line_.dy(), line_.dx());

    QPointF arrowP1 = point - QPointF(sin(angle + M_PI / 3) * arrowSize, cos(angle + M_PI / 3) * arrowSize);
    QPointF arrowP2 =
            point - QPointF(sin(angle + M_PI - M_PI / 3) * arrowSize, cos(angle + M_PI - M_PI / 3) * arrowSize);

    arrow_head_.clear();
    arrow_head_ << point << arrowP1 << arrowP2;
}
